#pragma once

#include "widget_config.h"
typedef int BOOL;
enum{

	MOUSE_EVENT_START = 0x1000,  /* Param1 = WPoint */
	MOUSE_LBUTTON_DOWN , 
	MOUSE_LBUTTON_UP,
	MOUSE_RBUTTON_DOWN,
	MOUSE_RBUTTON_UP,
	MOUSE_MOVE,
	MOUSE_EVENT_END,


	KEY_EVENT_START=MOUSE_EVENT_END+1,
	KEY_EVENT_DOWN,
	KEY_EVENT_UP,
	KEY_EVENT_END,


	ANIMATE_EVENT_START=0x1100,
	ANIMATE_WIDGET_UPDATE_READY,
	ANIMATE_EVENT_END,


};
typedef struct{
	unsigned int key_code,
	unsigned int rpt_cnt;
	unsigned int flag;
}WKEY_EVENT_T;
#define IS_KEY_EVENT(ev_code) \
	((ev_code)>KEY_EVENT_START && (ev_code)<KEY_EVENT_END)
typedef unsigned int EVENT_CODE_T;

class CModel;

typedef struct ModelListener ModelListener;

class DLL_EXP ModelEvent {
public:
	ModelEvent();
	virtual ~ModelEvent();
   EVENT_CODE_T         evCode;
   int bDelayHandleTime;
   CModel *       pModel;
   int			paramLen;
   int         dwParam;    // event specific data (pos, mode, etc.)
} ;
DLL_EXP ModelEvent* CloneEvent(ModelEvent* pSrc);

typedef void (*PFNLISTENER) (void *pUserData, ModelEvent *pEvent);
typedef void (*PFNLISTENERCANCEL) (ModelListener *pl);

struct ModelListener {
   ModelListener *pNext;
   ModelListener *pPrev;

   PFNLISTENER pfnListener;
   void *pListenerData;

   PFNLISTENERCANCEL pfnCancel;
   void *pCancelData;
   BOOL bEnableEventHandle;
};

class DLL_EXP CModel
{
public:
	CModel(void);
	~CModel(void);
	 ModelListener* m_pListenersHead;
	 ModelListener* m_pListenersTail;
	 int m_nListenersCount;



	int AddListener(ModelListener* pListener);
	void Notify(ModelEvent *pEvent);
	void NotifyEvent(int evCode,int param);
	void NotifyEvent(int evCode,int param,int paramlen);
	void NotifyDelay(ModelEvent* pEvent,int ms)
	{
		pEvent->bDelayHandleTime=ms;
		Notify(pEvent);
	}

	void RemoveListener(ModelListener* pListener);
};


#define LISTENER_Init(pcb,pcf,pcd) { (pcb)->pfnListener = (PFNLISTENER)(pcf);\
                                     (pcb)->pListenerData = (pcd); }

#define LISTENER_IsRegistered(pcb) (0 != (pcb)->pfnCancel)
#define LISTENER_Cancel(pcb) if (LISTENER_IsRegistered(pcb)) (pcb)->pfnCancel(pcb)

class DLL_EXP CEventDispatcher{
public:
	
	CModel evtModel;
	ModelListener evtListener;

	CEventDispatcher()
	{
		evtListener.bEnableEventHandle=true;
	}
	virtual ~CEventDispatcher()
	{
	}
	 virtual CModel* GetEventModel()
	{
		return &evtModel;
	}
	 virtual ModelListener* GetEventListener()
	{
		this->evtListener.pNext=0;
		this->evtListener.pPrev=0;
		this->evtListener.pCancelData=0;
		this->evtListener.pfnCancel=0;		
		return &evtListener;
	}
	virtual void SendModelEvent(int evCode,int param)
	{
		this->evtModel.NotifyEvent(evCode,param);
		
	}
	 virtual void EnableEventHandle()
	{
		evtListener.bEnableEventHandle=true;
		
	}
	 virtual void DisableEnventHandle()
	{
		evtListener.bEnableEventHandle=false;

	}
	virtual  void InitListener() = 0;

	virtual void DetachDispatcher(CEventDispatcher* pDisp)
	{
		this->evtModel.RemoveListener(pDisp->GetEventListener());
	}
	virtual void ConnectDispatcher(CEventDispatcher* pDisp)
	{
		this->evtModel.AddListener(pDisp->GetEventListener());
		pDisp->GetEventModel()->AddListener(&(this->evtListener));
	}

};

class DLL_EXP CUIViewInterface{
public :
	CUIViewInterface(){};
	~CUIViewInterface(){};
	virtual void OnInitialUpdate(){};
	virtual void OnViewSwitchOut(){};
	virtual void OnViewSwitchIn(){};
};

class DLL_EXP CMMTimerListener
{
public:
    virtual void Update(void* userData) = 0;
};

void StartMMTimer(int ms);
void AttachTimerListener(CMMTimerListener& listener);
void StopMMTimer();
void DetachTimerListener(CMMTimerListener& listener);
enum{
	
	APP_STATIC_START=0x1000,
	APP_STATIC_WEIQI_SERVER,
	APP_STATIC_END,
	APP_DYN_START=0x10000000,

};
typedef unsigned int APPLICATION_REG_ID;
class Application
{
public:
	APPLICATION_REG_ID app_id;
	CModel* pModel;
	ModelListener* pListener;
	Application(){};
	Application(APPLICATION_REG_ID id,CModel* pM,ModelListener* pL){
		app_id=id;
		pModel=pM;
		pListener=pL;
	};


};
